import {
	showToast,
	showModal,
	hideLoading,
	showLoading
} from '@/utils/uniTools'
// import store from '@/store'

// 请求队列
const pendingRequests = new Map()

// 默认配置 https://job.hyux.cn
const baseURL = 'http://fys6666.natapp1.cc/index.php'
const defaultConfig = {
	baseURL,
	maxRetryCount: 3,
	retryInterval: 5000,
	timeout: 10000,
	loadingDelay: 300,
	errorToastInterval: 2000,
}

// 请求优先级
const Priority = {
	HIGH: 3,
	MEDIUM: 2,
	LOW: 1,
}

// 请求取消令牌
class CancelToken {
	constructor() {
		this.promise = new Promise((resolve) => {
			this.resolve = resolve
		})
	}
}

// 生成请求key
function generateReqKey(config) {
	const {
		method,
		url,
		query,
		data
	} = config
	return [method, url, JSON.stringify(query), JSON.stringify(data)].join('&')
}

// 添加请求到队列
function addPendingRequest(config) {
	const requestKey = generateReqKey(config)
	config.cancelToken = config.cancelToken || new CancelToken()
	if (pendingRequests.has(requestKey)) {
		config.cancelToken.resolve('取消重复请求')
	} else {
		pendingRequests.set(requestKey, config)
	}
}

// 移除队列中的请求
function removePendingRequest(config) {
	const requestKey = generateReqKey(config)
	if (pendingRequests.has(requestKey)) {
		pendingRequests.delete(requestKey)
	}
}

// 清空所有请求
function clearPendingRequests() {
	pendingRequests.forEach((config) => {
		if (config.cancelToken) {
			config.cancelToken.resolve('取消所有请求')
		}
	})
	pendingRequests.clear()
}

// 兼容的 URL 参数序列化函数
function serializeQuery(query) {
	if (!query || Object.keys(query).length === 0) {
		return ''
	}

	const params = []
	Object.keys(query).forEach(key => {
		if (query[key] !== undefined && query[key] !== null) {
			params.push(encodeURIComponent(key) + '=' + encodeURIComponent(query[key]))
		}
	})
	return params.join('&')
}

// 请求拦截器
function requestInterceptor(config) {
	// 合并配置
	const mergedConfig = {
		...defaultConfig,
		...config,
		headers: {
			'Content-Type': 'application/json',
			...config.headers,
		},
		retryCount: config.retryCount !== undefined ? config.retryCount : 0,
		maxRetryCount: config.maxRetryCount !== undefined ? config.maxRetryCount : defaultConfig.maxRetryCount,
		retryInterval: config.retryInterval !== undefined ? config.retryInterval : defaultConfig.retryInterval,
	}

	// 添加token - 使用安全的存储获取方式
	let token = ''
	try {
		token = uni.getStorageSync('token') || ''
	} catch (e) {
		console.warn('获取 token 失败:', e)
	}

	if (token) {
		// Authorization
		mergedConfig.headers.Authorization = `${token}`
	}

	// 处理优先级
	if (mergedConfig.priority) {
		if (mergedConfig.priority === Priority.HIGH) {
			pendingRequests.forEach((reqConfig, key) => {
				if (reqConfig.priority < Priority.HIGH) {
					if (reqConfig.cancelToken) {
						reqConfig.cancelToken.resolve('高优先级请求取消')
					}
					pendingRequests.delete(key)
				}
			})
		}
	}

	addPendingRequest(mergedConfig)
	return mergedConfig
}

// 响应拦截器
function responseInterceptor(response) {
	removePendingRequest(response.config)

	const {
		data,
		statusCode
	} = response

	if (statusCode >= 200 && statusCode < 300) {
		// 处理业务状态码
		if (data.code === 200) {
			return data
		} else {
			const error = new Error(data.msg || `业务错误（code: ${data.code}）`)
			error.statusCode = data.code
			error.response = response
			throw error
		}
	}

	const error = new Error(data.msg || '请求失败')
	error.statusCode = statusCode
	error.response = response
	throw error
}

// 判断是否应该重试
function shouldRetry(error) {
	const statusCode = error.statusCode
	return !statusCode || statusCode === 404
}

// 错误处理函数
const errorHandlers = {
	400: (error) => {
		const responseData = error.response?.data
		return responseData?.msg || '请求参数错误'
	},
	401: async (error) => {
		// 使用安全的存储方式清除 token
		try {
			uni.removeStorageSync('token')
			uni.removeStorageSync('userInfo')
		} catch (e) {
			console.warn('清除存储失败:', e)
		}

		// 清除 Vuex 状态
		// if (store && store.commit) {
		// 	store.commit('user/CLEAR_TOKEN')
		// 	store.commit('user/CLEAR_USER_INFO')
		// }
		
		uni.showModal({
			title: '提示',
			content: '登录过期，请重新登录',
			confirmText: '去登录',
			cancelText: '取消',
			confirmColor:"#fd641d",
			success: async (res) => {
				if (res.confirm) {
					try {
						uni.redirectTo({
							url: '/pages/login/login'
						})
					} catch (err) {
						console.log(err);
					}
				}
			}
		})

		return '登录状态已过期'
	},
	403: (error) => {
		const responseData = error.response?.data
		return responseData?.message || '无权访问此资源'
	},
	404: () => '请求的资源不存在',
	500: (error) => {
		const responseData = error.response?.data
		return responseData?.msg || '服务器内部错误'
	},
	502: () => '网关错误',
	503: () => '服务不可用',
	504: () => '网关超时',
	default: (error) => {
		if (error.errno) {
			switch (error.errno) {
				case 'ETIMEDOUT':
					return '请求超时'
				case 'ECONNABORTED':
					return '连接中断'
				default:
					return error.message || '网络错误'
			}
		}
		return error.message || '请求失败'
	}
}

// 错误处理
async function errorHandler(error, config) {
	removePendingRequest(config)

	if (error.message && error.message.includes('取消')) {
		return Promise.reject(error)
	}

	// 重试逻辑
	if (config.retryCount < config.maxRetryCount && shouldRetry(error)) {
		config.retryCount++
		console.log(`请求失败，第${config.retryCount}次重试...`)
		await new Promise((resolve) => setTimeout(resolve, config.retryInterval))
		return request(config)
	}

	// 根据状态码处理错误
	const statusCode = error.statusCode
	const handler = errorHandlers[statusCode] || errorHandlers.default
	const errorMessage = await handler(error)

	// 错误提示
	if (config.errorToast !== false) {
		showErrorToast(errorMessage, config.errorToastInterval)
	}

	return Promise.reject({
		...error,
		message: errorMessage,
		retryCount: config.retryCount
	})
}

// 错误提示管理
let errorToastTimer = null
let lastErrorTime = 0
let lastErrorMessage = ''

function showErrorToast(message, interval = defaultConfig.errorToastInterval) {
	const now = Date.now()

	if (lastErrorMessage === message && now - lastErrorTime < interval) {
		return
	}

	lastErrorMessage = message
	lastErrorTime = now

	if (errorToastTimer) {
		clearTimeout(errorToastTimer)
	}

	showToast({
		title: message,
		icon: 'none',
		duration: 2000,
	})

	errorToastTimer = setTimeout(() => {
		lastErrorMessage = ''
		lastErrorTime = 0
	}, interval)
}

// Loading管理
let loadingTimer = null
let loadingCount = 0

function showRequestLoading(config) {
	if (config.loading === false) return

	loadingCount++

	if (loadingTimer) {
		clearTimeout(loadingTimer)
	}

	loadingTimer = setTimeout(() => {
		if (loadingCount > 0) {
			showLoading({
				title: config.loadingText || '加载中...',
				mask: true,
			})
		}
	}, config.loadingDelay)
}

function hideRequestLoading(config) {
	if (config.loading === false) return

	loadingCount = Math.max(0, loadingCount - 1)

	if (loadingCount === 0) {
		if (loadingTimer) {
			clearTimeout(loadingTimer)
			loadingTimer = null
		}
		hideLoading()
	}
}

// 构建完整URL（处理query参数）- 兼容版本
function buildFullUrl(baseURL, url, query) {
	let fullUrl = baseURL + url

	if (query && Object.keys(query).length > 0) {
		const queryString = serializeQuery(query)
		if (queryString) {
			fullUrl += (fullUrl.includes('?') ? '&' : '?') + queryString
		}
	}

	return fullUrl
}

// 核心请求方法
async function request(options) {
	let config
	try {
		config = requestInterceptor(options)

		// 全局加载
		showRequestLoading(config)

		let fullUrl = buildFullUrl(config.baseURL, config.url, config.query)
		
		const response = await uni.request({
			url: fullUrl,
			method: config.method || 'GET',
			data: config.data,
			header: config.headers,
			timeout: config.timeout,
		})
		
		// console.log('1111111111',response);

		return responseInterceptor({
			data: response.data,
			statusCode: response.statusCode,
			config,
		})
	} catch (error) {
		return errorHandler(error, config || options)
	} finally {
		if (config) {
			hideRequestLoading(config)
		}
	}
}

// 请求方法封装
const http = {
	// GET 请求
	get(url, query = {}, options = {}) {
		return request({
			url,
			method: 'GET',
			query,
			...options,
		})
	},

	// POST 请求
	post(url, data = {}, query = {}, options = {}) {
		return request({
			url,
			method: 'POST',
			data,
			query,
			...options,
		})
	},

	// PUT 请求
	put(url, data = {}, query = {}, options = {}) {
		return request({
			url,
			method: 'PUT',
			data,
			query,
			...options,
		})
	},

	// DELETE 请求
	delete(url, query = {}, options = {}) {
		return request({
			url,
			method: 'DELETE',
			query,
			...options,
		})
	},

	// 上传文件
	upload(url, filePath, name = 'file', formData = {}, options = {}) {
		return new Promise((resolve, reject) => {
			const fullUrl = buildFullUrl(options.baseURL || defaultConfig.baseURL, url, options.query)

			// 获取 token - 使用安全的方式
			let token = ''
			try {
				token = uni.getStorageSync('token') || ''
			} catch (e) {
				console.warn('获取 token 失败:', e)
			}

			const uploadTask = uni.uploadFile({
				url: fullUrl,
				filePath,
				name,
				formData,
				header: {
					Auth: token,
					...options.headers,
				},
				success: (res) => {
					if (res.statusCode === 200) {
						try {
							const data = JSON.parse(res.data)
							resolve(data)
						} catch (e) {
							resolve(res.data)
						}
					} else {
						const error = new Error(res.errMsg || '上传失败')
						error.statusCode = res.statusCode
						reject(error)
					}
				},
				fail: reject,
			})

			if (options.onProgressUpdate) {
				uploadTask.onProgressUpdate(options.onProgressUpdate)
			}
		})
	},

	// 下载文件
	download(url, options = {}) {
		return new Promise((resolve, reject) => {
			const fullUrl = buildFullUrl(options.baseURL || defaultConfig.baseURL, url, options.query)

			// 获取 token - 使用安全的方式
			let token = ''
			try {
				token = uni.getStorageSync('token') || ''
			} catch (e) {
				console.warn('获取 token 失败:', e)
			}

			const downloadTask = uni.downloadFile({
				url: fullUrl,
				header: {
					Auth: token,
					...options.headers,
				},
				success: (res) => {
					if (res.statusCode === 200) {
						resolve(res.tempFilePath)
					} else {
						const error = new Error(res.errMsg || '下载失败')
						error.statusCode = res.statusCode
						reject(error)
					}
				},
				fail: reject,
			})

			if (options.onProgressUpdate) {
				downloadTask.onProgressUpdate(options.onProgressUpdate)
			}
		})
	},

	// 设置全局配置
	setConfig(newConfig) {
		Object.assign(defaultConfig, newConfig)
	},

	// 取消所有请求
	cancelAllRequests() {
		clearPendingRequests()
	},

	// 优先级常量
	Priority,
}

export default http